home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / bootcode.arc / BOOT.ASM next >
Assembly Source File  |  1991-06-13  |  4KB  |  138 lines

  1. ;
  2. ;A customized boot routine, which will load an application program
  3. ;  from tracks 1 through HIGHEST_TRACK and start it running.
  4. ;
  5. ;The segment to which the boot routine will be relocated so that it will
  6. ;  be out of the way of the program to be loaded.
  7. moved_segment    segment at 0020h
  8.     org    0
  9. moved_routine    label    far
  10. moved_segment    ends
  11. ;
  12. ;The segment in which the application program will be loaded
  13. program_segment    segment at 0040h
  14.     org    100h
  15. start_point    label    far    ;Since it is a COM program, the application
  16.                 ; program will start at offset 100 (hex)
  17. program_segment    ends
  18. ;
  19. highest_track    equ    1    ;The highest-numbered track to be read in
  20. ;
  21. cseg    segment
  22.     assume    cs:cseg
  23. ;
  24. ;While this is a COM program, it is designed to be independent of its
  25. ;  location in memory, and so it need not start at offset 100 (hex).
  26. ;
  27. start    proc    near
  28. ;
  29. ;Set the stack to 0020:0200, at the end of the unused interrupt vector area
  30. ;
  31.     cli        ;Turn off interrupts so that we can't get caught
  32.             ; with the stack segment set the new way and the
  33.             ; stack pointer set the old way
  34.     mov    ax,0020h
  35.     mov    ss,ax
  36.     mov    sp,0200h
  37.     sti
  38. ;
  39. ;Move the rest of the boot routine to the unused vector area at 0020:0000
  40. ;
  41.     mov    ax,moved_segment
  42.     mov    es,ax    ;The extra segment will be the destination segment
  43.     mov    ax,cs
  44.     mov    ds,ax    ;The code segment will be the source, since we're
  45.             ; relocating the program code
  46.     call    self    ;Since we can't be sure where the routine is loaded,
  47.             ; we'll execute a call to the next instruction to get
  48.             ; the instruction pointer pushed on the top of the
  49.             ; stack
  50. self:
  51.     pop    si    ;Get the instruction pointer back off the stack
  52.     add    si,((offset c1)-(offset self))    ;Adjust SI, which will be the
  53.             ; source for the move, to point the the start of the
  54.             ; working part of the boot routine
  55.     sub    di,di    ;The destination for the move will be 0020:0000
  56.     mov    cx,256    ;Number of bytes to move
  57.     rep movsb    ;Move the rest of the routine to 0020:0000
  58.     jmp    moved_routine    ;Execute a far jump to the start of the
  59.             ; moved portion of the boot routine
  60. ;
  61. ;By the time the program reaches this point, the following code will have
  62. ;  been moved to 0020:0000.
  63. ;
  64. c1:
  65.     sub    ax,ax    ;0 is the number of the diskette reset function
  66.     int    13h    ;Call BIOS to reset the disk 
  67.     mov    ax,program_segment
  68.     mov    es,ax
  69.     mov    ds,ax    ;Point the data and extra segments to point to
  70.             ; the segment in which the program will go
  71.     mov    bx,offset start_point    ;point to the location at which
  72.             ; the program is to be loaded.  COM programs must
  73.             ; start at CS:100 (hex)
  74.     mov    ch,1    ;Initial track #
  75. lp1:
  76. ;
  77. ;Get the current track (4K bytes).  For 9 sectors/track, you will need
  78. ;  to set a new disk parameter block-see Appendix A of the Tech Ref manual.
  79. ;Try to read the track-retry 10 times if the read attempt
  80. ;  is not successful, and if still unsuccessful, enter an infinite loop.
  81. ;
  82.     mov    bp,10    ;# times to retry
  83. disk_retry_loop:
  84.     push    bp
  85.     sub    dx,dx    ;Head 0, drive 0
  86.     mov    cl,1    ;Start at sector 1
  87.     mov    ah,2    ;BIOS read function #
  88.     mov    al,8    ;We want to read 8 sectors
  89.     int    13h    ;Invoke BIOS to read this track
  90.     pop    bp
  91. ;
  92. ;Check for error
  93. ;
  94.     jnc    track_is_in
  95. ;
  96. ;If there is an error, reset disk and retry
  97. ;
  98.     push    bp
  99.     sub    ah,ah
  100.     int    13h    ;reset disk
  101.     pop    bp
  102.     dec    bp
  103.     jnz    disk_retry_loop
  104. ;
  105. ;If we've already retried many times, enter an infinite loop
  106. ;
  107. error_loop:
  108.     jmp    error_loop
  109. ;
  110. ;We've got this track
  111. ;
  112. track_is_in:
  113.     add    bx,1000h    ;Point to next load point (4K farther on)
  114.     inc    ch        ;Point to the next track
  115.     cmp    ch,highest_track    ;See if we've read all the tracks in
  116.     jbe    lp1        ;If not, read the next track
  117. ;
  118. ;Set the stack for the application program.  Stack goes at the far end of
  119. ;  the program segment.  Turn off interrupts so we can't get caught between
  120. ;  setting SS and SP.
  121. ;
  122.     cli
  123.     mov    ax,program_segment
  124.     mov    ss,ax
  125.     mov    sp,0FC00h    ;Set this value to 0000h if you have more
  126.                 ; than 64K of memory, to leave as much room
  127.                 ; as possible free for the program.  A lower
  128.                 ; value is required if you have less than
  129.                 ; 64K so that the stack will fit in memory
  130.     sti
  131. ;
  132. ;The program is all loaded in.  Jump to the start of it.
  133. ;
  134.     jmp    start_point
  135. start    endp
  136. cseg    ends
  137.     end    start    ;Program is to begin at label START
  138.